`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    15:40:25 04/12/2011 
// Design Name: 
// Module Name:    InstructionDecode 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module InstructionDecode(clk, pcIn, instrIn, writeAddr, writeData, RegWrite_from_WB, doJmp, 
	jumpPC, jumpInstr, RegWrite, MemtoReg, branch, MemRead, MemWrite, ALUSrc1, 
	ALUSrc2, ALUOp, readData1, readData2, signExt, rs, rt, writeDst, RorNot, mt, pcOut, reset);
	
	input clk;
	input [15:0] pcIn;
	input [15:0] instrIn;
	input [3:0] writeAddr;
	input [15:0] writeData;
	input RegWrite_from_WB;
	input reset;
	
	output doJmp; //Feedback to IF
	//output doBra; //MEM control
	output [3:0] jumpPC; //Feedback to IF
	output [11:0] jumpInstr; //Feedback to IF
	output RegWrite; //WB control
	output MemtoReg; //WB control
	output branch; //MEM control
	output MemRead; //MEM control
	output MemWrite; //MEM control
	//output RegDst; //WB data
	output ALUSrc1; //EX control
	output ALUSrc2; //EX control
	output [3:0] ALUOp; //EX control
	output [15:0] readData1; //EX data
	output [15:0] readData2; //EX data
	output [15:0] signExt; //EX data
	//output wbMuxSel; //
	output [3:0] rs;
	output [3:0] rt;
	output [3:0] writeDst; //WB data
	output RorNot;
	output [15:0] mt;
	output [15:0] pcOut;
	
	wire flushSel;

/*	reg branch;
	reg [3:0] readReg2;
	reg [15:0] readData1;
	reg [15:0] readData2;
	reg [15:0] mt;
	reg [3:0] writeDst;
	reg [1:0] liRlw;
	reg RorNot;
	reg ID_Flush;
	reg stallSignal;
	reg instrControl; */
	
	//always be feeding the correct jump bits back to IF
	assign jumpPC = pcIn[15:12];
	assign jumpIntr = instrIn[11:0];
	assign pcOut = pcIn;
	assign rs = instrIn[11:8];
	assign rt = instrIn[7:4];
	
	//mux to decide rt for R-type or b for branches
	Mux_2to1_4bits i_Mux1(
		.a(instrIn[7:4]), //Rt
		.b(4'b0111), //$b
		.sel(branch), 
		.out(readReg2)); //Who gets read
	
	//place values into Registers block
	RegFile i_RegFile(
	.clk(clk),
	.readReg1(instrIn[11:8]),
	.readReg2(readReg2),
	.writeReg(writeAddr),
	.writeData(writeData),
	.RegWrite(RegWrite_from_WB),
	.readData1(readData1),
	.readData2(readData2),
	.mt(mt),
	.reset(reset));
		
	//sign extend to place in ID/EX buffer
	SignExtend i_SignExtend(
	.a(instrIn[7:0]),
	.y(signExt));
	
	Controller i_Controller(
		.instrControl(instrIn[15:12]), 
		.RegWrite(RegWrite), 
		.MemtoReg(MemtoReg), 
		.branch(branch), 
		.MemRead(MemRead), 
		.MemWrite(MemWrite), 
//		.RegDst(RegDst), 
		.ALUSrc1(ALUSrc1),
		.ALUSrc2(ALUSrc2), 
		.ALUOp(ALUOp), 
		.doJmp(doJump), 
//		.doBra(doBra), 
		.liRlw(liRlw), 
		.ID_Flush(ID_Flush), 
//		.wbMuxSel(wbMuxSel), 
		.RorNot(RorNot));
		
	//mux to decide between li, R-type, lw
	Mux_4to1_4bits i_mux(
		.a(instrIn[11:8]), //Rs
		.b(instrIn[3:0]),  //Rd
		.c(4'b0110), //$mr
		.d(4'b0000), //Illegal
		.sel(liRlw), 
		.out(writeDst));
	


endmodule
